package ca.jsbr.as2js_lib.display.canvas 
{
	import ca.jsbr.as2js_lib.utils.geom.Rect;
	import ca.jsbr.as2js_lib.utils.KeyManager;
	import ca.jsbr.as2js_lib.utils.MouseManager;
	import flash.utils.setInterval;
	import flash.utils.setTimeout;
	import js.document;
	import js.element.canvas.CanvasRenderingContext2D;
	import js.element.HTMLCanvasElement;
	import js.event.Event;
	import js.event.MouseEvent;
	import js.window;
	import jslib.jslib;


	public class CanvasStage extends Node2D
	{
		
		static public const EVT_READY:String = "ready";
		static public var instance:CanvasStage;
		
		private var _canvas:HTMLCanvasElement=null;
		private var _ctx:CanvasRenderingContext2D;
		static private const _id:int = -1;
		private var _lastTime:Number;
		private var _defaultFrameDelta:Number;
		private var _frameDelta:Number;
		private var _stageDescription:StageDescription;
		private var _played:Boolean;
		
		public function CanvasStage(description:StageDescription) 
		{
			instance = this;
			_stageDescription = description;
			if (_stageDescription.stageId)
			{
				if (jslib.ready)
					initCanvas(document.getElementById(_stageDescription.stageId));
				else
					window.addEventListener("load", onLoaded);
			}
			_name = "stage";
		}
		
		public function initCanvas(stage:HTMLCanvasElement):void
		{
			_canvas = stage;
			if (_width > 0)
				_canvas.width = _width;
			else
				_width = parseInt(_canvas.width);
				
			if (_height > 0)
				_canvas.height = _height;
			else
				_canvas.width = _width;
				
			if(!_canvas) {
				_canvas=document.createElement("canvas");
				_canvas.width=200;
				_canvas.height=200;
			}
			//KeyManager.getInstance().setTagListner(window);
			_canvas.addEventListener("click",onClick)
			_ctx = _canvas.getContext("2d");
			MouseManager.getInstance().start(_canvas);
			start();
		}
		
		public function start():void
		{
			_lastTime = new Date().getTime();
			_defaultFrameDelta = 1000 / _stageDescription.fps;
			_played = true;
			if (_stageDescription.repaintMode==StageDescription.REPAINT_FIX)
			{
				setInterval(onRenderFrame, _defaultFrameDelta);
			}
			else if (_stageDescription.repaintMode==StageDescription.REPAINT_ADAPTABLE)
			{  
				setTimeout(onRenderFrame, _defaultFrameDelta);
			}
			else if (_stageDescription.repaintMode==StageDescription.REPAINT_BROWSER){
				window.requestAnimFrame(onRenderFrame, _canvas);
			}
		}
		
		public function stop():void
		{
			_played = false;
		}
		
		private function onClick(e:MouseEvent):void 
		{
		
		}
		
		
		override public function get stageX():Number 
		{
			return 0;
		}
		
		override public function get stageY():Number 
		{
			return 0;
		}
		
		override public function get stage():CanvasStage 
		{
			return this;
		}
		
		public function getCanvas():HTMLCanvasElement
		{
			return _canvas;
		}
		
		public override function get width():Number 
		{
			return _width;
		}
		
		
		public override function set width(value:Number):void 
		{
			_width=value
			if(_canvas)
				_canvas.width = value;
		}
		
		public override function get height():Number 
		{
			return _height;
		}
		
		public override function set height(value:Number):void 
		{
			_height=value;
			if(_canvas)
				_canvas.height = value;
		}	
		
		static public function get id():int 
		{
			_id++;
			return _id;
		}
		
		public function get frameDelta():Number 
		{
			return _frameDelta;
		}
		
		public function get stageDescription():StageDescription 
		{
			return _stageDescription;
		}
		
		public function get context():CanvasRenderingContext2D 
		{
			return _ctx;
		}
		
		private	function onRenderFrame():void
		{
			//RENDER MODE
			if (_stageDescription.renderMode == StageDescription.RENDER_ALL) {
				_ctx.clearRect(0, 0, _width, _height);
				render(_ctx);
			}
			if (_stageDescription.renderMode == StageDescription.RENDER_GRID) {
				_ctx.clearRect(0, 0, _width, _height);
				render(_ctx, new Rect(0, 0, 100, 100));
			}
			
			//RESET
			MouseManager.getInstance().postRender();
			var time:Number = new Date().getTime();
			_frameDelta = time-_lastTime;
			
			//RECALL
			if (_stageDescription.repaintMode==StageDescription.REPAINT_ADAPTABLE) {  
				_defaultFrameDelta = 1000 / _stageDescription.fps - 1;
				setTimeout(onRenderFrame, _defaultFrameDelta+(_defaultFrameDelta-(time-_lastTime)));
			}
			else if (_stageDescription.repaintMode==StageDescription.REPAINT_BROWSER) {
				window.requestAnimFrame(onRenderFrame, _canvas);
			}
			_lastTime = time;
		}
		
		override function render(context:CanvasRenderingContext2D):void 
		{
			for (var i:int = 0; i < _childs.length;i++ )
			{
				var child:View = _childs[i];
				child.preRender();
				child.render(context);
			}
		}
		
		private function onLoaded(e:Event)
		{
			window.removeEventListener(Event.LOAD, onLoaded);
			initCanvas(document.getElementById(_stageDescription.stageId));
		}
	}

}
